﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ecdl.demo.model.expression {
    public abstract class ExpressionState {
        public ExpressionState() {

        }

        public ExpressionState(Expression expression)
            : this() {
            this.Expression = expression;
        }

        public Expression Expression { get; private set; }

        public virtual bool IsOk { get; set; }

        public abstract string GetCause(bool positive);
    }

    public class ErrorexpressionState : ExpressionState {
        private Exception exception;
        public ErrorexpressionState(Expression expression, Exception e)
            : base(expression) {
            IsOk = false;
            exception = e;
        }

        public override string GetCause(bool positive) {
            return "Die Bedingung hat einen Fehler verursacht: " + exception.Message;
        }
    }

    public class MultiExpressionState : ExpressionState {

        public MultiExpressionState(Expression expression)
            : base(expression) {
            ChildExpressions = new List<ExpressionState>();
        }


        public List<ExpressionState> ChildExpressions { get; private set; }

        public override string GetCause(bool positive) {

            StringBuilder cause = new StringBuilder();
            cause.AppendLine("Folgende Bedingungen müssen erfüllt sein: ");

            foreach (var child in ChildExpressions) {
                cause.Append("\t").Append("- ").AppendLine(child.GetCause(positive));
            }

            return cause.ToString();
        }
    }

    public class LeafExpressionState : ExpressionState {
        private string posCause;
        private string negCause;

        public LeafExpressionState(Expression expression)
            : base(expression) {
        }

        public LeafExpressionState(Expression expression, string cause, bool isOk)
            : this(expression) {
            posCause = cause;
            negCause = cause;
            IsOk = isOk;
        }

        public void SetCause(string positiveCause, string negativeCause) {
            this.posCause = positiveCause;
            this.negCause = negativeCause;
        }

        public override string GetCause(bool positive) {
            if (positive) {
                return posCause;
            } else {
                return negCause;
            }
        }
    }

    public class NotExpressionState : ExpressionState {
        private ExpressionState notExpression;

        public NotExpressionState(Expression expression, ExpressionState notExpression)
            : base(expression) {
            this.notExpression = notExpression;
        }

        public override bool IsOk {
            get {
                return !notExpression.IsOk;
            }
            set {
                //ignore
            }
        }

        public override string GetCause(bool positive) {
            return notExpression.GetCause(!positive);
        }
    }
}
